package com.ice.body.rpc.api;

import com.arcsoft.face.FaceFeature;
import com.ice.base.controller.BaseController;
import com.ice.base.model.SysLoginModel;
import com.ice.base.result.AjaxResult;
import com.ice.base.result.ResponseResult;
import com.ice.base.service.SysLoginService;
import com.ice.base.util.BaseUtil;
import com.ice.base.util.FaceEngineTool;
import com.ice.base.util.RedisUtil;
import com.ice.base.util.VoiceUtil;
import com.ice.body.business.model.ReagentStock;
import com.ice.body.business.vo.ReagentEpcVo;
import com.ice.body.hardware.model.DeviceFace;
import com.ice.body.hardware.model.DeviceMachine;
import com.ice.body.hardware.model.DeviceVoice;
import com.ice.body.hardware.service.DeviceMachineService;
import com.ice.body.hardware.service.DeviceVoiceService;
import com.ice.body.hardware.service.FaceToRoomService;
import com.ice.body.rpc.dto.ReagentStockDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import sun.misc.BASE64Decoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created with GuoYanBin.
 * Description:
 * Date: 2022-11-09
 * Time: 04:03
 */
@RestController
@ApiIgnore(value = "rpc接口-结算通道一体机")
@RequestMapping("/rpcSettlement")
@Slf4j
public class RpcSettlementApi extends BaseController{
    //---------------------------库存试剂-----------------------start
 
    @Resource
    private FaceToRoomService faceToRoomService;
    @Resource
    private SysLoginService sysLoginService;
    @Resource
    private DeviceMachineService machineService;
    @Resource
    private DeviceVoiceService deviceVoiceService;
    @Autowired
    private FaceEngineTool faceEngineTool;
    @Autowired
    private RedisUtil redisUtil;
    @Resource
    private VoiceUtil voiceUtil;

    public static volatile Boolean process = true;


    /**
     * 使用中  结算
     * @param dto
     * @param request
     * @param img
     * @return
     */
    @RequestMapping("/matchFaceFromJS")
    public AjaxResult<T> matchFaceFromJS(@RequestBody ReagentStockDto dto,HttpServletRequest request, String img) {

        String warehouseId = dto.getWarehouseId();
        log.info(warehouseId +"号库结算");
        if(StringUtils.isEmpty(warehouseId)){
            log.info("warehouseId 为空");
            return AjaxResult.error("warehouseId 为空");
        }
        List list = dto.getList();
        try {
            return faceToRoomService.settlement(warehouseId, list);
        } catch (Exception e) {
            log.info(warehouseId + "号库房结算异常！");
            e.printStackTrace();
            return AjaxResult.error("结算异常");
        }

    }

    /**
     * 一体机刷脸出门
     * @param img
     * @return
     */
    @RequestMapping("/matchFaceFromJS22222222222222222222222")
    public AjaxResult<T> matchFaceFromJS(HttpServletRequest request, String img) {
        AjaxResult r = AjaxResult.error();

        String ip = BaseUtil.getIPAddress(request);
        if (!process) {
            log.info("。。。。一体机刷脸出门处理繁忙。。。。");
            return AjaxResult.error("结算处理繁忙,请稍后");
        }
        try {
            DeviceMachine machineModel = machineService.getByIp(ip);
            if (machineModel==null) {
                return AjaxResult.error("不存在该ip下的结算台");
            }
            String warehouseId = machineModel.getWarehouseId();
            //生成jpg图片
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String path = BaseUtil.getVideoPath() + "faceImg/compare/" + sdf.format(new Date()) + ".png";
            //保存图片
            parseLoginFace(img, path);
            //人脸对比
            SysLoginModel u = matchFace(path);
            if (u != null) {
                log.info(u.getRealName() + " 虹软面部识别出门!!!");
                //开始退出流程  面部识别对象传输一个warehouseid的作用
                DeviceFace model = new DeviceFace();
                model.setIp(ip);
                model.setWarehouseId(machineModel.getWarehouseId());
                // 2代表出门
                faceToRoomService.executeSingle(2, u, model);
            } else {
                DeviceVoice voiceModel = deviceVoiceService.getByWarehouseId(warehouseId);
                voiceUtil.sendVoice(voiceModel.getIp(),voiceModel.getPort(),"人脸对比失败,非法用户!");
                log.info("人脸对比失败-用户不存在");
                return r;

            }
            r = ResponseResult.success();
        } catch (Exception e) {
            log.info("一体机面部识别结算异常！");
            e.printStackTrace();
        }finally {
            process= true;
        }
        return r;
    }

    private void parseLoginFace(String img, String savePath) {
        try {
            if (img == null) //图像数据为空
                return;
            // System.out.println("开始解码");
            BASE64Decoder decoder = new BASE64Decoder();
            //Base64解码
            img = img.replace("data:image/png;base64,", "");
            byte[] b = decoder.decodeBuffer(img);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {//调整异常数据
                    b[i] += 256;
                }
            }
            OutputStream out = new FileOutputStream(savePath);
            out.write(b);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }

    public SysLoginModel matchFace(String savePath) {
        File file = null;
        try {
            file = new File(savePath);
            if (!file.exists()) {
                return null;
            }
            //开始人脸对比
            FaceFeature currentFace = faceEngineTool.pathGetFace(savePath);
            Set<Object> faceKeys = redisUtil.hItem("faceMap");
            for (Object key : faceKeys) {
                FaceFeature faceFeature = (FaceFeature) redisUtil.hget("faceMap", key.toString());
                float score = faceEngineTool.CheckFace(currentFace, faceFeature);
                if (score >= 0.75) {
                    return sysLoginService.selectById(key.toString());
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (file != null && file.exists()) {
                file.delete();
            }
        }
    }



    @ApiIgnore(value = "系统后台删除出入库试剂信息")
    @PostMapping("/business/delReaInfo")
    public AjaxResult delReaInfo(HttpServletRequest request,String epcCode) {
        String ip = BaseUtil.getIPAddress(request);
        try {
            DeviceMachine machineModel = machineService.getByIp(ip);
            if (machineModel==null) {
                System.out.println("不存在该ip下的结算通道");
                return AjaxResult.error("不存在该ip下的结算通道!");
            }
            String wareHouseId = machineModel.getWarehouseId();
            log.info("删除redis试剂 warehouId："+wareHouseId +",epc:" +epcCode);
            List<ReagentStock> ckEcList = (List<ReagentStock>) redisUtil.get(wareHouseId + "ckList");

            if (ckEcList != null && ckEcList.size() > 0) {
                Iterator<ReagentStock> it=ckEcList.iterator();
                while(it.hasNext()) {
                    if (it.next().getEpcCode().equals(epcCode)) {
                        log.info("移除出库列表中：" + epcCode);
                        it.remove();
                    }
                }
                redisUtil.set(wareHouseId + "ckList", ckEcList);// 把试剂信息重新放进redis中
            }
            List<ReagentStock> ghEcList = (List<ReagentStock>) redisUtil.get(wareHouseId + "ghList");
            if (ghEcList != null && ghEcList.size() > 0) {
                Iterator<ReagentStock> it=ghEcList.iterator();
                while(it.hasNext()) {
                    if (it.next().getEpcCode().equals(epcCode)) {
                        it.remove();
                    }
                }
                redisUtil.set(wareHouseId + "ghList", ghEcList);// 把试剂信息重新放进redis中
            }

        } catch (Exception e) {
            AjaxResult.error("删除失败");
        }
        return AjaxResult.success("删除成功");
    }

    @RequestMapping("/t1")
    public void test11() {
        System.out.println("测试");

            ReagentEpcVo v1  = new ReagentEpcVo();
            v1.setEpcCode("111");
            ReagentEpcVo v2  = new ReagentEpcVo();
            v2.setEpcCode("222");


            List<ReagentEpcVo> list = new ArrayList<>();
            list.add(v1);
            list.add(v2);

            redisUtil.set("1ckList" , list);

            try {
                System.out.println("原本数组大小：" + list.size());
                List<ReagentEpcVo> ckEcList = (List<ReagentEpcVo>) redisUtil.get("1ckList");
                if (ckEcList != null && ckEcList.size() > 0) {
                    Iterator<ReagentEpcVo> it=ckEcList.iterator();
                    while(it.hasNext()) {
                        if (it.next().getEpcCode().equals("111")) {
                            System.out.println("去除数组中：" + "111");
                            it.remove();
                        }
                    }

             /*   for (int i = 0; i < ckEcList.size(); i++) {
                    if (ckEcList.get(i).getEpcCode().equals(epcCode)) {
                        ckEcList.remove(i);
                    }
                }*/
                    redisUtil.del(1 + "ckEcList");
                    System.out.println("删除后数组大小：" + ckEcList.size());
                    redisUtil.set(1 + "ckList", ckEcList);// 把试剂信息重新放进redis中

                    List<ReagentEpcVo> l2 = (List<ReagentEpcVo>) redisUtil.get("1ckList");
                    System.out.println("删除后从redis取出数组大小：" + ckEcList.size() + l2.get(0).getEpcCode());
                }
            }catch (Exception e){
                e.printStackTrace();
            }



    }

}
